<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- concurrent.qdoc -->
  <title>OpenCL and QtConcurrent</title>
  <link rel="stylesheet" type="text/css" href="style/style.css" />
  <script src="scripts/jquery.js" type="text/javascript"></script>
  <script src="scripts/functions.js" type="text/javascript"></script>
  <script src="./scripts/superfish.js" type="text/javascript"></script>
  <link rel="stylesheet" type="text/css" href="style/superfish.css" />  <script src="./scripts/narrow.js" type="text/javascript"></script>
  <link rel="stylesheet" type="text/css" href="style/narrow.css" />
  <!--[if IE]>
<meta name="MSSmartTagsPreventParsing" content="true">
<meta http-equiv="imagetoolbar" content="no">
<![endif]-->
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="style/style_ie6.css">
<![endif]-->
<!--[if IE 7]>
<link rel="stylesheet" type="text/css" href="style/style_ie7.css">
<![endif]-->
<!--[if IE 8]>
<link rel="stylesheet" type="text/css" href="style/style_ie8.css">
<![endif]-->
</head>
<body class="" onload="CheckEmptyAndLoadList();">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td align="left" valign="top" width="150"><img src="images/qt-logo.png" align="left" border="0" />&nbsp;&nbsp;<img src="images/qtopencl-logo.png" border="0" /></td>
<td width="1">&nbsp;&nbsp;</td><td class="postheader" valign="center"> <a href="index.html"><font color="#004faf">Home</font></a>&nbsp;&middot; <a href="qtopencl-all-classes.html"><font color="#004faf">All Classes</font></a></td>
</table>              <li>OpenCL and QtConcurrent</li><h1 class="title">OpenCL and QtConcurrent</h1>
<span class="subtitle"></span>
<!-- $$$concurrent.html-description -->
<div class="descr"> <a name="details"></a>
<p><a href="http://doc.qt.nokia.com/4.6/threads-qtconcurrent.html">QtConcurrent</a> provides high-level APIs that make it possible to write multi-threaded programs without using low-level threading primitives such as mutexes, read-write locks, wait conditions, or semaphores. It was designed for use on multi-core systems with a homogeneous CPU architecture, shared memory between the cores, and pre-compiled functions to be executed in threads.</p>
<p>OpenCL has a very different design, using heterogeneous computing resources that are scattered across multiple CPU and GPU architectures, which may not be sharing the same memory address space, and which usually compile the functions to be executed at runtime.</p>
<p>OpenCL programs are structured to prepare arguments, upload them explicitly, run the compiled &quot;kernel&quot; on the arguments, and then download the results. A large part of the OpenCL API is concerned with argument upload and download. See the <a href="vectoradd.html">Vector Addition Example</a> for a simple outline of the process. QtConcurrent does not currently provide upload/download facilities because it assumes that the compute resource can access the arguments via the shared memory address space.</p>
<p>The QtOpenCL library makes it easy for programmers familiar with QtConcurrent to use QtOpenCL with the same coding style they are used to. In particular, it provides an override for <a href="qtconcurrent.html#run">QtConcurrent::run</a>() that can be used with <a href="qclkernel.html">QCLKernel</a> objects:</p>
<pre class="highlightedCode brush: cpp">    kernel.setGlobalWorkSize(100, 100);
    QFuture&lt;void&gt; future = QtConcurrent::run(kernel, a1, b1);
    future.waitForFinished();</pre>
<p>This will create a background thread on the main CPU to enqueue the kernel for execution and to wait for the kernel to complete.</p>
<p>Only 5 arguments can be passed to a kernel using <a href="qtconcurrent.html#run">QtConcurrent::run</a>(), which is the same as for regular functions and QtConcurrent. Use explicit <a href="qclkernel.html#setArg">QCLKernel::setArg</a>() calls and <a href="qclkernel.html#runInThread">QCLKernel::runInThread</a>() for kernels with more than 5 arguments.</p>
<p>Because kernels do not have return values, <a href="qtconcurrent.html#run">QtConcurrent::run</a>() on a <a href="qclkernel.html">QCLKernel</a> will always return a QFuture&lt;void&gt;.</p>
<p>The main advantage of QFuture&lt;void&gt; compared to <a href="qclevent.html">QCLEvent</a> is that it can be used with QFutureWatcher to receive signal notification of when a kernel completes execution:</p>
<pre class="highlightedCode brush: cpp">    QFutureWatcher&lt;void&gt; *watcher = new QFutureWatcher&lt;void&gt;(this);
    watcher-&gt;setFuture(QtConcurrent::run(kernel, a1, b1));
    connect(watcher, SIGNAL(finished()), this, SLOT(eventFinished()));</pre>
<p>The kernel object must not be reused until the background thread finishes execution of the kernel. Thus, the following code will have unexpected effects:</p>
<pre class="highlightedCode brush: cpp">    QFuture&lt;void&gt; future1 = QtConcurrent::run(kernel, a1, b1);
    QFuture&lt;void&gt; future2 = QtConcurrent::run(kernel, a2, b2);
    future1.waitForFinished();
    future2.waitForFinished();</pre>
<p>The recommended method to run the same kernel multiple times in a background thread is as follows:</p>
<pre class="highlightedCode brush: cpp">    void runKernelTwice(QCLKernel &amp;kernel)
    {
        kernel(a1, b1);
        kernel(a2, b2).waitForFinished();
    }

    QFuture&lt;void&gt; future = QtConcurrent::run(runKernelTwice, kernel);</pre>
<p>See <a href="qclkernel.html#kernels-and-qtconcurrent">Kernels and QtConcurrent</a> and <a href="qclevent.html#toFuture">QCLEvent::toFuture</a>() for more information.</p>
<p><a href="index.html">Return to Home</a></p>
</div>
<!-- @@@concurrent.html -->
<p /><address><hr /><div align="center">
<table width="100%" cellspacing="0" border="0"><tr class="address">
<td align="left">Copyright &copy; 2010 Nokia Corporation</td>
<td align="right">QtOpenCL Documentation</td>
</tr></table></div></address>  <script src="scripts/functions.js" type="text/javascript"></script>
  <script type="text/javascript">
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-4457116-5']);
  _gaq.push(['_trackPageview']);
  (function() {
  var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
  ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
  var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();
  </script>
</body>
</html>
